/*
 * Copyright 2009 Jamie Gennis
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.code.gwt.remoteaction.server;

/**
 * Some utility functions to help with reflection-related functionality.
 *
 * @author jgennis
 */
public class Utils {

  public static final String INTERNAL_PACKAGE = "com.google.code.gwt.remoteaction.client.internal";

  protected static final String RESULT_SUFFIX = "Result";

  protected static final String PROXY_SUFFIX = "Proxy";

  /**
   * Derive the canonical source name of the generated action result class from
   * the name of the Action class.
   *
   * @param actionClassName the canonical source name of the Action class
   * @return the canonical source name of the action result class
   */
  public static String getResultCanonicalClassName(String actionClassName) {
    String simpleName = getResultSimpleClassName(actionClassName);
    String canonicalName = INTERNAL_PACKAGE + "." + simpleName;
    return canonicalName;
  }

  /**
   * Derive the simple source name of the generated action result class from
   * the name of the Action class.
   *
   * @param actionClassName the canonical source name of the Action class
   * @return the simple source name of the action result class
   */
  public static String getResultSimpleClassName(String actionClassName) {
    String simpleName = makeSimplifiedName(actionClassName) + RESULT_SUFFIX;
    return simpleName;
  }

  /**
   * Derive the canonical source name of the generated remote action service
   * proxy class from the name of the service interface.
   *
   * @param serviceInterfaceName the canonical source name of the Action class
   * @return the canonical source name of the remote action service proxy
   */
  public static String getProxyCanonicalClassName(String serviceInterfaceName) {
    String simpleName = getProxySimpleClassName(serviceInterfaceName);
    String canonicalName = INTERNAL_PACKAGE + "." + simpleName;
    return canonicalName;
  }

  /**
   * Derive the simple source name of the generated remote action service proxy
   * class from the name of the service interface.
   *
   * @param serviceInterfaceName the canonical source name of the Action class
   * @return the simple source name of the remote action service proxy
   */
  public static String getProxySimpleClassName(String serviceInterfaceName) {
    String simpleName = makeSimplifiedName(serviceInterfaceName) + PROXY_SUFFIX;
    return simpleName;
  }

  /**
   * Get the reference type corresponding to a given primitive type.
   *
   * @param primitiveType the primitive type
   * @return the reference type
   */
  public static Class<?> getReferenceType(Class<?> primitiveType) {
    if (primitiveType == null)
      throw new IllegalArgumentException("The primitiveType argument may not be null");
    if (!primitiveType.isPrimitive())
      throw new IllegalArgumentException("The primitiveType argument is not a primitive type");
    if (Void.TYPE.equals(primitiveType))
      return Void.class;
    if (Boolean.TYPE.equals(primitiveType))
      return Boolean.class;
    if (Byte.TYPE.equals(primitiveType))
      return Byte.class;
    if (Character.TYPE.equals(primitiveType))
      return Character.class;
    if (Short.TYPE.equals(primitiveType))
      return Short.class;
    if (Integer.TYPE.equals(primitiveType))
      return Integer.class;
    if (Long.TYPE.equals(primitiveType))
      return Long.class;
    if (Float.TYPE.equals(primitiveType))
      return Float.class;
    if (Double.TYPE.equals(primitiveType))
      return Double.class;
    throw new IllegalStateException("Unknown primitive type: " + primitiveType.getCanonicalName());
  }

  /**
   * Make a name suitable for a simple name out of a canonical name.
   *
   * @param canonicalName a canonical name
   * @return a simple name derived from the canonical name
   */
  public static String makeSimplifiedName(String canonicalName) {
    return canonicalName.replace('.', '_');
  }

  /**
   * Make a parameterGetter method name for a given property name.
   *
   * @param propertyName the property name
   * @return the parameterGetter method name
   */
  public static String makeGetterName(String propertyName) {
    return "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
  }
}
